<?php
/**
 * MenuModel.class.php      菜单模型
 *
 * @author                  mashanling(msl-138@163.com)
 * @date                    2012-03-29 09:46:19
 * @last modify             2012-09-10 16:53:53 by mashanling
 */

!defined('ROOT') && exit('Access Denied');

class MenuModel extends CommonModel {
    protected $auto = array(//自动填充
        'is_show'    => 'getCheckboxValue',//是否显示
        'sort_order' => 'unsigned#data',//排序 by mashanling on 2012-09-10 16:53:47
    );
    /**
     * 数据表字段信息
     * filter: 数据类型，array(数据类型(string,int,float...),Filter::方法参数1,参数2...)
     * validate: 自动验证，支持多个验证规则
     *
     * @see Model.class.php create()方法对数据过滤
     * @see CommonModel.class.php __construct()方法设置自动验证字段_validate
     */
    protected $db_fields = array (
        'menu_id'          => array('filter' => 'int', 'validate' => 'unsigned#PRIMARY_KEY,INVALID'),//自增主键
        'parent_id'        => array('filter' => 'int', 'validate' => 'unsigned#PLEASE_SELECT,PARENT_MENU'),//父级菜单id

        //菜单名称
        'menu_name'        => array('validate' => array('notblank#MODULE_NAME_MENU', 'checkLength#MODULE_NAME_MENU,NAME#value|0|30')),

        //控制器
    	'controller'       => array('validate' => array('checkController#PLEASE_ENTER,CONTROLLER#data', 'checkLength#CONTROLLER#value|0|20')),

        //备注
        'memo'             => array('validate' => array('return#MEMO', 'checkLength#MEMO#value|0|60')),
        //操作方法
        'action'           => array('validate' => array('checkAction#PLEASE_ENTER,ACTION#data', 'checkLength#ACTION#value|0|20')),
        'is_show'          => array('filter' => 'int'),//是否显示
        'sort_order'       => array('filter' => 'int', 'validate' => 'unsigned#ORDER#-2'),//排序
        '_priv_id'         => array('validate' => 'return#PERMISSION'),//权限
    );
    protected $pk = 'menu_id';//主键
    protected $true_table_name = TB_MENU;//表

	/**
     * 删除后置操作，生成菜单缓存及删除管理员权限
     *
     * @see Model::_after_delete()
     *
     * @return void 无返回值
     */
    protected function _after_delete($data, $options = array()) {
        $this->module->create();
        $options['table'] = TB_ADMIN_ROLE_PRIV;
        $this->db->delete($options);//删除管理员权限

        $options['table'] = TB_FIELD;
        $this->db->delete($options);//删除表单域 by mashanling on 2012-09-10 17:50:55

        R('Role/setCache');//角色缓存
    }

    /**
     * 插入后置操作
     *
     * @author                  mashanling(msl-138@163.com)
     * @date                    20:54 2012-7-8
     * @last modify             2012-09-10 16:55:35 by mashanling
     *
     * @see Model::_after_insert()
     *
     * @return void 无返回值
     */
    protected function _after_insert($data, $options) {
        $pk_field = $this->getPk();
        !isset($data['sort_order']) && $this->db->execute('UPDATE ' . TB_MENU . " SET sort_order={$data[$pk_field]} WHERE {$pk_field}={$data[$pk_field]}");
    }

    /**
     * 更新后置操作
     *
     * @see Model::_after_update()
     *
     * @return void 无返回值
     */
    protected function _after_update($data, $options) {
        $count = count($data);

        if ($count == 1) {

            if (isset($data['is_show'])) {//显示，隐藏
                $this->module->create();
            }
        }
    }

	/**
     * 验证操作方法是否已经存在
     *
     * @param string $action 操作方法
     * @param array  $data   _POST数据
     *
     * @return mixed 验证成功，返回true。否则，如果未输入，返回提示信息，否则返回false
     */
    protected function checkAction($action, $data) {

        if ($action === '') {//如果未输入，提示输入
            return false;
        }

        $controller  = isset($data['controller']) ? $data['controller'] : '';
        $pk_value    = isset($data[$this->pk]) ? $data[$this->pk] : 0;
        $menu_arr    = $this->getCache();

        foreach ($menu_arr as $menu_id => $menu) {

            if (strcasecmp($action, $menu['action']) == 0 && strcasecmp($controller, $menu['controller']) == 0 && $pk_value != $menu_id && $controller != '#' && $action != '#') {
                return L('EXIST_SAME_CONTROLLER_AND_ACTION') . ': <br /><span style="color: #666;font-weight: bold;">' . $this->module->nav($menu_id, 'menu_name') . '</span>';
            }
        }

        return true;
    }

    /**
     * 验证控制器是否已经存在
     *
     * @param string $controller 控制器
     * @param array  $data       _POST数据
     *
     * @return mixed 验证成功，返回true。否则，如果未输入，返回提示信息，否则返回false
     */
    protected function checkController($controller, $data) {

        if ($controller === '') {//如果未输入，提示输入
            return false;
        }

        $parent_id = isset($data['parent_id']) ? $data['parent_id'] : 0;
        $pk_value  = isset($data[$this->pk]) ? $data[$this->pk] : 0;
        $menu_arr  = $this->getCache();

        foreach ($menu_arr as $menu_id => $menu) {

            if ($parent_id == 0 && strcasecmp($controller, $menu['controller']) == 0 && $pk_value != $menu_id && $menu['parent_id'] == 0 && $controller != '#') {
                return L('CONTROLLER,EXIST') . ': <br /><span style="color: #666;font-weight: bold;">' . $this->module->nav($menu_id, 'menu_name') . '</span>';
            }
        }

        return true;
    }

    /**
     * 设置角色权限
     *
     * @param int   $menu_id
     * @param mixed $role_id 角色id串(数组)
     *
     * @return bool
     */
    function setMenuPriv($menu_id, $role_id) {
        if (!$role_id) {//无权限，直接删除
            $this->db->execute('DELETE FROM ' . TB_ADMIN_ROLE_PRIV . ' WHERE menu_id=' . $menu_id);
        }
        else {
            $role_data   = $this->getCache(0, 'Role');
            $menu_data   = $this->getCache($menu_id);
            $priv_arr    = $this->module->diffMenuPriv($menu_data ? array_keys($menu_data['priv']) : '', $role_id);

            if ($delete = $priv_arr['delete']) {//删除的

                if ($role_data) {

                    foreach($delete as $role_id) {

                        if (isset($role_data[$role_id])) {
                            unset($role_data[$role_id]['priv'][$menu_id]);
                        }
                    }
                }

                $this->db->execute('DELETE FROM ' . TB_ADMIN_ROLE_PRIV . ' WHERE menu_id=' . $menu_id . ' AND role_id IN(' . join(',', $delete) . ')');
            }

            if ($add = $priv_arr['add']) {//新增的
                $priv_letter = $priv_arr['priv_letter'];
                $add         = array_unique($add);
                $values      = '';

                foreach($add as $role_id) {

                    if (isset($role_data[$role_id])) {
                        $role_data[$role_id]['priv'][$menu_id] = strtolower($menu_data['controller'] . $menu_data['action']);
                    }

                    $values .= ",({$role_id},{$menu_id})";
                }

                $this->db->execute('INSERT INTO ' . TB_ADMIN_ROLE_PRIV . '(role_id,menu_id) VALUES' . trim($values, ','));

            }
        }

        C('NO_PRIV_ACTION', 'RolesetCache');
        R('Role/setCache', array(isset($role_data) ? $role_data : false));//重新生成管理角色缓存 by mashanling on 10:50 2012-07-24

        return true;
    }//end setMenuPriv
}